package com.code2roc.fastboot.framework.extra.submitlock;

import com.code2roc.fastboot.framework.extra.enums.SystemErrorCodeEnum;
import com.code2roc.fastboot.framework.model.Result;
import com.code2roc.fastboot.framework.redis.RedisLockUtil;
import com.code2roc.fastboot.framework.util.CommonUtil;
import com.code2roc.fastboot.framework.util.StringUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

@Aspect
@Component
@Order(value = 100)
public class RepeatSubmitAspect {
    private static Logger logger = LoggerFactory.getLogger(RepeatSubmitAspect.class);
    @Autowired
    private RedisLockUtil redisLockUtil;

    /**
     * 切面点 指定注解
     */
    @Pointcut("@annotation(com.code2roc.fastboot.framework.extra.submitlock.SubmitLock) " +
            "|| @within(com.code2roc.fastboot.framework.extra.submitlock.SubmitLock)")
    public void repeatSubmitAspect() {

    }

    /**
     * 拦截方法指定为 repeatSubmitAspect
     */
    @Around("repeatSubmitAspect()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        SubmitLock submitLock = method.getAnnotation(SubmitLock.class);
        if (submitLock != null) {
            HttpServletRequest request = CommonUtil.getRequest();
            String token = request.getHeader("token");
            if (!StringUtil.isEmpty(token)) {
                String path = request.getServletPath();
                String key = "submitLock|" + token + "|" + path;
                String clientId = CommonUtil.getNewGuid();
                if (redisLockUtil.lockAutoReset(key, submitLock.expire())) {
                    // 获取锁成功
                    return point.proceed();
                } else {
                    return Result.errorResult().setMsg(SystemErrorCodeEnum.ErrorCode.RepeatSubmitError.get_name()).setCode(SystemErrorCodeEnum.ErrorCode.RepeatSubmitError.get_value());
                }
            } else {
                return point.proceed();
            }
        } else {
            return point.proceed();
        }
    }
}
